home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-30 | 9.8 KB | 390 lines | [TEXT/MMCC] |
- /*
- ** MakeTemplate.c
- */
-
- short def_vRef = 0; // folder for definition (input) files
- long def_parID = 0;
- short def_fRef = 0; // file reference for current definition file
- Handle defText; // handle for definition file
-
- short out_vRef = 0; // folder for output files
- long out_parID = 0;
- short out_fRef = 0; // file reference for current output file
- Handle outText; // handle for new output file
-
- extern Str63 outFileName; // name of template macro file name (typically ___.tm.h)
- extern Str63 defnFileName; // name of template definition file name (typically ___.tem)
- extern char ch_type [256];
-
- Str255 junkBfr; // junk characters buffer
- Boolean hadToken; // true if a token occurred on this line
-
- Boolean inTemplateDefn; // true if defining (rather than declaring) template
-
- char outClass[255]; // class of template we're building
- char wildcard[255]; // class of wildcard we're defining (macro argument)
- short tokenState; // state of token parser
- // 0 = normal operation
- // 1 = encountered 'template', expecting '<'
- // 2 = encountered 'template <', expecting 'class'
- // 3 = encountered 'template <class', expecting (type)
- // 4 = encountered 'template <class (type)', expecting '>'
- // 5 = encountered 'template <class (type)>', expecting 'class' or function type
- // 6 = encountered 'template <class (type)> class', expecting (class)
- // then cycles back to 0
- // 10 = encountered '<', check for type
- // 11 = encountered '< (type)', expecting '>'
- // 20 = encountered (class), name of base class, expecting '(' – constructor/destructor
-
-
- void OutCStr(char* str);
- void OutPStr(unsigned char* str);
- extern void ErrMsg ( unsigned char * why , unsigned char * file , short code );
-
-
- Boolean OpenOutfile()
- {
- OSErr err;
-
- err = HCreate(out_vRef, out_parID, outFileName, 'MPCC', 'TEXT');
- if (err == -48) { // duplicate file name, delete old file (dangerous... I know!)
- err = HDelete(out_vRef, out_parID, outFileName);
- if (!err) {
- err = HCreate(out_vRef, out_parID, outFileName, 'MPCC', 'TEXT');
- }
- }
-
- if (err) {
- ErrMsg("\pCreating", outFileName, err);
- return true;
- }
-
- err = HOpenDF ( out_vRef , out_parID , outFileName , fsRdWrPerm , & out_fRef ) ;
- if ( err ) {
- ErrMsg ( "\pOpening" , outFileName , err ) ;
- return true;
- }
- outText = NewHandle (0) ;
- if ( ! outText ) {
- ErrMsg ( "\pAllocating" , outFileName , MemError ( ) ) ;
- FSClose ( out_fRef ) ;
- return true;
- }
-
- OutCStr("// ");
- OutPStr(outFileName);
- OutCStr("\r//\r// Macro template file\r// Generated by Template Munger\r\r");
-
- junkBfr[0] = 0;
- outClass[0] = 0;
- wildcard[0] = 0;
- hadToken = false;
- inTemplateDefn = false;
-
- return false;
-
- }
-
-
- void CloseOutfile()
- {
- OSErr err;
- long size ;
-
- size = GetHandleSize ( outText ) ;
- err = SetEOF ( out_fRef , size ) ;
- if ( ! err ) {
- err = SetFPos ( out_fRef , fsFromStart , 0L ) ;
- }
- if ( err ) {
- ErrMsg ( "\pFinishing" , outFileName , err ) ;
- FSClose ( out_fRef ) ;
- DisposeHandle ( outText ) ;
- return ;
- }
- HLock ( outText ) ;
- err = FSWrite ( out_fRef , & size , * outText ) ;
- if ( err ) {
- ErrMsg ( "\pWriting" , outFileName , err ) ;
- FSClose ( out_fRef ) ;
- DisposeHandle ( outText ) ;
- return ;
- }
- err = FSClose ( out_fRef ) ;
- if ( ! err ) {
- err = FlushVol ( NULL , out_vRef ) ;
- }
- DisposeHandle ( outText ) ;
- if ( err ) {
- ErrMsg ( "\pClosing" , outFileName , err ) ;
- }
- }
-
-
- void OutCStr(char* str)
- {
- long len = 0;
- char* p = str;
-
- while (*p++)
- len++;
- PtrAndHand(str, outText, len);
- }
-
- void OutPStr(unsigned char* str)
- {
- long len = *str;
- PtrAndHand(str+1, outText, len);
- }
-
- void OutJunkChar(char theChar)
- {
- if ((tokenState == 10) && ((theChar != ' ') && (theChar != '\t'))) {
- junkBfr[++junkBfr[0]] = '<'; // make sure that <> or <= doesn't trigger template expansion
- tokenState = 0;
- }
- junkBfr[++junkBfr[0]] = theChar;
- if (junkBfr[0] > 200) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
- }
-
- Boolean OutToken(char* theToken)
- {
- Boolean tokValid = true; // set to false if invalid token for context
- if ((junkBfr[0]) && (tokenState == 0)) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
-
- hadToken = true;
- switch (tokenState) {
- case 0: // normal operation: check for keywords
- if (!strcmp(theToken, "template")) {
- tokenState = 1; // found a template declaration, parse it
- break;
- }
- if (!strcmp(theToken, "<")) {
- tokenState = 10; // might be a reference to the template, parse it
- if (junkBfr[0]) { // get other characters out in proper sequence
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
- break;
- }
- if (!strcmp(theToken, outClass)) { // template class name, see if it's constructor/destructor
- tokenState = 20;
- break;
- }
- OutCStr(theToken); // neither of the above, just copy it
- break;
-
- case 1: // got 'template', expect '<'
- if (strcmp(theToken, "<")) {
- tokValid = false;
- tokenState = 0;
- OutCStr("template"); // just copy the invalid stuff to file
- OutToken(theToken);
- break;
- }
- tokenState++; // valid input, continue chain
- break;
-
- case 2: // got 'template <', expect 'class'
- if (strcmp(theToken, "class")) {
- tokValid = false;
- tokenState = 0;
- OutCStr("template <"); // just copy the invalid stuff to file
- OutToken(theToken);
- break;
- }
- tokenState++; // valid input, continue chain
- break;
-
- case 3: // got 'template <class', expect (type)
- if (ch_type[theToken[0]] != 4) { // first character must be alpha
- tokValid = false;
- tokenState = 0;
- OutCStr("template <class "); // just copy the invalid stuff to file
- OutToken(theToken);
- break;
- }
- strcpy(wildcard, theToken); // keep this thing around
- tokenState++; // valid input, continue chain
- break;
-
- case 4: // got 'template <class (type)', expect '>'
- if (strcmp(theToken, ">")) {
- tokValid = false;
- tokenState = 0;
- OutCStr("template <class "); // just copy the invalid stuff to file
- OutCStr(wildcard);
- OutToken(theToken);
- break;
- }
- tokenState++; // valid input, continue chain
- break;
-
- case 5: // got 'template <class (type)>', expect 'class' or function type
- if (inTemplateDefn) {
- tokenState = 0; // just dump the 'template <class (type)>' line
- junkBfr[0] = 0;
- OutToken(theToken);
- break;
- } else {
- if (strcmp(theToken, "class")) { // declaring class, expect 'class' only
- tokValid = false;
- tokenState = 0;
- OutCStr("template <class "); // just copy the invalid stuff to file
- OutCStr(wildcard);
- OutCStr(">");
- OutToken(theToken);
- break;
- }
- tokenState++; // valid input, continue chain
- break;
- }
-
- case 6: // got 'template <class (type)> class', expect '(type)'
- if (ch_type[theToken[0]] != 4) { // first character must be alpha
- tokValid = false;
- tokenState = 0;
- OutCStr("template <class "); // just copy the invalid stuff to file
- OutCStr(wildcard);
- OutToken(theToken);
- break;
- }
- strcpy(outClass, theToken); // keep this thing around
-
- OutCStr("\r#define TM_DECLARE_"); // valid input, write macro header
- OutCStr(outClass);
- OutCStr("(");
- OutCStr(wildcard);
- OutCStr(") \\\rclass ");
- OutCStr(outClass);
- OutCStr("_ ## ");
- OutCStr(wildcard);
-
- junkBfr[0] = 0; // clear junk buffer
- tokenState = 0; // resume normal operation
- break;
-
- case 10: // got '<', might get (wildcard type)
- if (strcmp(theToken, wildcard)) {
- tokenState = 0; // nope… just treat it like anything else
- OutCStr("<"); // make sure the '<' charater gets out properly
- OutToken(theToken); // and print this other token
- break;
- }
- tokenState++; // valid input, continue chain
- break;
-
- case 11: // got '< (wildcard)', expecting '>'
- if (strcmp(theToken, ">")) {
- tokValid = false;
- tokenState = 0;
- OutCStr("<"); // just copy the invalid stuff to file
- OutCStr(wildcard);
- OutToken(theToken);
- break;
- }
-
- OutCStr("_ ## "); // was valid, substitute template expansion
- OutCStr(wildcard);
- junkBfr[0] = 0;
- tokenState = 0; // back to normal
- break;
-
- case 20: // got class name, look for '('
- if (!strcmp(theToken, "(")) {
- OutCStr(outClass); // found '(', substitute expanded constructor/destructor name
- OutCStr("_ ## ");
- OutCStr(wildcard);
- }
- else
- OutCStr(outClass); // no '(' found, just print it as is
- tokenState = 0; // print the stuff
- OutToken(theToken);
- break;
-
- default: // something broke!
- Message("\rInternal error");
- tokenState = 0;
- OutToken(theToken);
- break;
-
- }
-
- hadToken = true;
- return tokValid; // token was valid…
-
- }
-
- void OutNewLine()
- {
- short i;
- char* p;
-
- if (tokenState != 0) {
- OutJunkChar(' '); // ignore new lines in the midst of template declarations
- return;
- }
-
- i = junkBfr[0]+1;
- p = (char*) &junkBfr[i]; // strip all trailing spaces from "junk buffer"
- while (--p, --i) {
- if ((*p != ' ') && (*p != '\t'))
- break; // non-blank, must print it
- else
- junkBfr[0]--; // remove this character
- }
-
- if ((!hadToken) && (!junkBfr[0])) // completely blank line, skip it
- return;
-
- if (junkBfr[0]) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
- hadToken = false;
- OutCStr(" \\\r"); // be sure to continue macro definition
- }
-
- void EndTemplateDeclaration()
- {
- if (junkBfr[0]) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
- OutCStr("};\r");
- }
-
- void StartTemplateDefn()
- {
- if (junkBfr[0]) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
-
- OutCStr("\r\r\r#define TM_DEFINE_"); // write macro header – using same class name
- OutCStr(outClass);
- OutCStr("(");
- OutCStr(wildcard);
- OutCStr(") \\\r");
-
- junkBfr[0] = 0; // clear junk buffer
- tokenState = 0; // resume normal operation
- inTemplateDefn = true; // …except we want to allow template function definitions
- }
-
-
- void EndTemplateDefn()
- {
- if (junkBfr[0]) {
- OutPStr(junkBfr);
- junkBfr[0] = 0;
- }
- OutCStr("\r\r");
- }
-